package com.fatri.lessionsimple.util.study

import android.provider.Contacts
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.channels.produce
import java.io.FileOutputStream

/**
 * 协程demo
 */
class CorotineDemo {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
//            runBlockingTest()
//            launchTest()

            coroutineCommunicateDemo()


            //启动方式1
//            runBlocking {
//                //协程嵌套
//                val job = launch(context = Dispatchers.IO) {
//                    repeat(1000) {
//                        println("挂起中 $it。。。")
//                        delay(500L)
//                    }
//
//
//                }
//
//
//                val job2 = async {
//                    delay(500)
//                    return@async "hello"
//                }
//                println("job2输出:${job2.await()}")
//
//
//                delay(1300L)
//                println("main:主线程等待中")
//                job.cancel()
//                job.join()  //cancel又join不起作用
//                println("main:即将完成退出")


        }
    }
}

/**
 * runBlocking中的delay会阻塞当前线程
 */
fun runBlockingTest() {
    runBlocking {
        println("run blocking start")
        delay(3000)
        println("run blocking end...")
    }
    println("current thread:${Thread.currentThread().name}")
}

/**
 * 1、launch协程的delay不阻塞当前线程，只阻塞当前协程
 * 2、当运行的线程退出后，协程未完成的任务也退出
 */
fun launchTest() {
    GlobalScope.launch( ) {
        println("run blocking start")
        delay(3000)
        println("run blocking end...")
    }

    Thread.sleep(1000)
    println("current thread  :${Thread.currentThread().name}")
//    for (i in 0..10) {
//        println("$i")
//        Thread.sleep(1000)
//    }
    println("current thread exit:${Thread.currentThread().name}")
}


/**
 * 协程通信
 */
fun coroutineCommunicateDemo() {
   runBlocking {
       val c = Channel<Int>()
       GlobalScope.launch {
           get(c)
       }
       GlobalScope.launch {
           put(c)
       }
       Unit
   }



    FileOutputStream("").use {

    }
}

suspend fun get(channel: Channel<Int>) {
    GlobalScope.produce<Int> {

    }
    MainScope()
    while (true) {
        println(channel.receive())
    }
}

suspend fun put(channel: Channel<Int>) {
    var i = 0
    while (true) {
        channel.send(i++)
    }
}
